package com.googlecode.droidircclient;

import android.app.Activity;
import android.widget.ViewAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.TranslateAnimation;
import android.view.View.OnTouchListener;
import android.view.MotionEvent;

public class ViewScroller extends ViewAnimator {

	private GestureDetector scroller;
	private float yOrig;
	private final int MAX_ERR_MARGIN = 200;	
	
	private class ScrollMotionDetector extends SimpleOnGestureListener {
		private final int MAX_ERR_MARGIN = 200;
		private final int MIN_VELOCITY = 100;	
		private final int MIN_DIST = 100;
		private ViewAnimator flip;
		private Animation SlideLeftIn;
		private Animation SlideRightIn;
		private Animation SlideLeftOut;
		private Animation SlideRightOut;
		
		public ScrollMotionDetector(ViewScroller flipper){
			flip = flipper;
			SlideLeftIn = 	new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT, 1, Animation.RELATIVE_TO_PARENT, 0,
				Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0);  
			SlideRightIn = new TranslateAnimation(
					Animation.RELATIVE_TO_PARENT, -1, Animation.RELATIVE_TO_PARENT, 0,
					Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0);
			SlideLeftOut = new TranslateAnimation(
					Animation.RELATIVE_TO_PARENT, 0,Animation.RELATIVE_TO_PARENT, 1,
					Animation.RELATIVE_TO_PARENT, 0,Animation.RELATIVE_TO_PARENT, 0);
			SlideRightOut = new TranslateAnimation(
					Animation.RELATIVE_TO_PARENT, 0,Animation.RELATIVE_TO_PARENT, -1,
					Animation.RELATIVE_TO_PARENT, 0,Animation.RELATIVE_TO_PARENT, 0);
			SlideLeftIn.setDuration(500);
			SlideRightIn.setDuration(500);
			SlideLeftOut.setDuration(500);
			SlideRightOut.setDuration(500);
		}
				
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
			//System.out.println("Fling detected!");
			if(Math.abs(e2.getX()-e1.getX()) > MIN_DIST && Math.abs(velocityX) > MIN_VELOCITY && Math.abs(e2.getY() - e1.getY()) < MAX_ERR_MARGIN){
				if(e2.getX() > e1.getX()){
					int modulus = flip.getChildCount();
					int here = flip.getDisplayedChild();
					int there = (here-1 < 0)? modulus-1:Math.abs( (here-1)%modulus );//This check in necessary because java DOESN'T DO MODULO RIGHT
					View kid = flip.getCurrentView();//assume all child views have the same dimensions
					SlideLeftOut.initialize(kid.getWidth(),kid.getHeight(),flip.getWidth(),flip.getHeight());
					SlideRightIn.initialize(kid.getWidth(),kid.getHeight(),flip.getWidth(),flip.getHeight());
					flip.setOutAnimation(SlideLeftOut);
					flip.setInAnimation(SlideRightIn);
					flip.setDisplayedChild( there );
					//System.out.println("Attempting to slide from " + here + " to " + there + "(" + modulus + " total)...");
					return true;
				}
				else{
					int modulus = flip.getChildCount();
					int here = flip.getDisplayedChild();
					int there = Math.abs( (here+1)%modulus );
					View kid = flip.getCurrentView();
					SlideLeftIn.initialize(kid.getWidth(),kid.getHeight(),flip.getWidth(),flip.getHeight());
					SlideRightOut.initialize(kid.getWidth(),kid.getHeight(),flip.getWidth(),flip.getHeight());
					flip.setInAnimation(SlideLeftIn);
					flip.setOutAnimation(SlideRightOut);
					flip.setDisplayedChild( there );
					//System.out.println("Attempting to slide from " + here + " to " + there + "(" + modulus + " total)...");
					return true;					
				}
			}
			
			return false;
		}//onFling
		
	}
	
	
	public ViewScroller(Context context){
		super(context);
		scroller = new GestureDetector(new ScrollMotionDetector(this)){
			public boolean onTouchEvent(MotionEvent e){
				//System.out.println("Recieved " + e.toString());
				return super.onTouchEvent(e);
			}
			
		};
	}
	
	public ViewScroller(Context context, AttributeSet attrs){
		super(context,attrs);
		scroller = new GestureDetector(new ScrollMotionDetector(this)){
			public boolean onTouchEvent(MotionEvent e){
				//System.out.println("Recieved " + e.toString());
				return super.onTouchEvent(e);
			}
		};
	}

	public boolean onInterceptTouchEvent(MotionEvent e){
		//System.out.println("Intercepted event " + e.toString() + "!");
		if (e.getAction() == MotionEvent.ACTION_DOWN) yOrig = e.getY();
		if (Math.abs(yOrig - e.getY()) >= MAX_ERR_MARGIN) return false;
		return onTouchEvent(e);//scroller.onTouchEvent(e);
	}
	
	public boolean onTouchEvent(MotionEvent e){
		if (e.getAction() == MotionEvent.ACTION_DOWN) yOrig = e.getY();
		if (Math.abs(yOrig - e.getY()) >= MAX_ERR_MARGIN){
			//System.out.println("Returning False.");
			return false;
		}
		scroller.onTouchEvent(e);
		return false;
	}
	
}
